package com.pkk.penguin.frame.know.java.driven;

import com.pkk.penguin.frame.know.java.driven.bean.JavaBean;
import com.pkk.penguin.frame.know.java.driven.bean.XmlBean;
import com.pkk.penguin.frame.know.java.driven.support.JavaBeanInjectionSupport;
import java.util.Arrays;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @description: 注解驱动器开发注册时类
 * @author: peikunkun
 * @create: 2020-07-17 11:41
 **/
@ComponentScan(basePackages = "com.pkk", lazyInit = false, excludeFilters = {
    //@Filter(value = {Service.class}, type = FilterType.ANNOTATION),//注解形式过滤
    //@Filter(value = {ComponentService.class}, type = FilterType.ASSIGNABLE_TYPE),//bean类形式
    //@Filter(value = {ComponentCustomScan.class}, type = FilterType.CUSTOM)//bean类形式
}
)
@Slf4j
@Configuration
public class DrivenMainTests {




  @Test
  public void Administrator_11_20200717114149_Injection() {
    log.info("欢迎使用单元测试方法【Administrator_11()_20200717114149】");
    log.info("此方法测试描述：【依据xml进行bean的依赖注入到ioc容器中】");
    final ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
        "dirven/xml-injection.xml");
    final XmlBean xmlBeanByName = (XmlBean) classPathXmlApplicationContext.getBean("xmlBean");
    final XmlBean xmlBeanByClass = (XmlBean) classPathXmlApplicationContext.getBean(XmlBean.class);
    log.info(xmlBeanByName.toString());
    log.info(xmlBeanByClass.toString());
  }


  @Test
  public void Administrator_27_20200717115108_Injection() {
    log.info("欢迎使用单元测试方法【Administrator_27()_20200717115108】");
    log.info("此方法测试描述：【依据java配置方式进行bean的依赖注入到ioc容器中】");
    final ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
        JavaBeanInjectionSupport.class);
    final JavaBean beanByClass = annotationConfigApplicationContext.getBean(JavaBean.class);
    final JavaBean beanByName = (JavaBean) annotationConfigApplicationContext.getBean("javaBean");
    log.info("class方式获取:" + beanByClass.toString());
    log.info("beanName方式:" + beanByName.toString());

    final Class<JavaBean> javaBeanClass = JavaBean.class;
    final String[] beanNamesForType = annotationConfigApplicationContext.getBeanNamesForType(javaBeanClass);
    log.info("class为:" + javaBeanClass.getSimpleName() + ",其BeanName为:");
    Arrays.stream(beanNamesForType).forEach((beanName) -> log.info(beanName));
  }


  @Test
  public void Administrator_51_20200717143729_ComponentScan() {
    log.info("欢迎使用单元测试方法【Administrator_51()_20200717143729】");
    log.info("此方法测试描述：【包扫描,可以让其扫描@Conpoent,@Controller,@Service,@Repository注解,然后注入到Spring的IOC容器中】");
    final ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
        "dirven/xml-injection.xml");
    final String[] beanDefinitionNames1 = classPathXmlApplicationContext.getBeanDefinitionNames();
    Arrays.stream(beanDefinitionNames1).forEach((beanName) -> log.info(beanName));
    log.info("---------------------------------------------");
    final ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
        DrivenMainTests.class);
    final String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
    Arrays.stream(beanDefinitionNames).forEach((beanName) -> log.info(beanName));
  }


  @Test
  public void Administrator_81_20200717152612_() {
    System.out.println("欢迎使用单元测试方法【Administrator_81()_20200717152612】");
    System.out.println("此方法测试描述：【Scoped的运用(protype类型每次获取bean的时候都会触发一次创建bean的方法执行,singleton则会在创建容器的时候进行一次初始化操作)】");
    final ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
        "dirven/xml-injection.xml");

    final ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
        JavaBeanInjectionSupport.class);

    final XmlBean xmlBeanByName1 = (XmlBean) classPathXmlApplicationContext.getBean("xmlBean");
    final XmlBean xmlBeanByName2 = (XmlBean) classPathXmlApplicationContext.getBean("xmlBean");
    log.info("******************下面两个获取在scope为protype时获取bean一次就会触发一次***********************");
    final JavaBean javaBeanByClass1 = (JavaBean) annotationConfigApplicationContext.getBean(JavaBean.class);
    final JavaBean javaBeanByClass2 = (JavaBean) annotationConfigApplicationContext.getBean(JavaBean.class);

    log.info("{}-{}={}", xmlBeanByName1, xmlBeanByName2, xmlBeanByName1 == xmlBeanByName2);
    log.info("{}-{}={}", javaBeanByClass1, javaBeanByClass2, javaBeanByClass1 == javaBeanByClass2);
  }


  @Test
  public void Administrator_102_20200717165818_Lasy() {
    System.out.println("欢迎使用单元测试方法【Administrator_102()_20200717165818】");
    System.out.println("此方法测试描述：【Lazy进行懒加载,只有在使用的时候才会进行创建bean】");
    final ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
        "dirven/xml-injection.xml");
    final ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
        JavaBeanInjectionSupport.class);
    log.info("初始化IOC容器完成");
    final JavaBean javaBeanByClass1 = (JavaBean) annotationConfigApplicationContext.getBean(JavaBean.class);
    log.info("JavaBean创建时采用单例模式,懒加载模式,在使用的时候进入IOC容器中");
    final XmlBean xmlBeanByName1 = (XmlBean) classPathXmlApplicationContext.getBean("xmlBean");
    log.info("XmlBean创建时需采用单例模式,非懒加载模式,在创建IOC容器的时候进行创建");
  }


}
